package com.zhiling.www.service;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zhiling.www.entity.*;
import com.zhiling.www.mapper.MoneyRecordMapper;
import com.zhiling.www.mapper.UserMapper;
import com.zhiling.www.util.JwtUtils;
import com.zhiling.www.util.PhoneCodeUtils;
import com.zhiling.www.util.Tools;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService{

    private Logger logger = Logger.getLogger(UserServiceImpl.class);
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MoneyRecordMapper moneyRecordMapper;

    //用户登录验证
    @Override
    public Result login(User user) {
        Result result = new Result();
        String uname = user.getUserName();
        String upwd = user.getUserPwd();
        if (StringUtils.isEmpty(uname)) {
            result.setCode(400);  //登录失败
            result.setMsg("请输入账号");
            return result;
        }
        if (StringUtils.isEmpty(upwd)) {
            result.setCode(400);  //登录失败
            result.setMsg("请输入登录密码");
            return result;
        }
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userName", uname);
        //数据库中查到的用户
        User userByUserName = userMapper.selectOneByExample(example);
        if (userByUserName == null) {
            result.setCode(400);  //登录失败
            result.setMsg("账号不存在，请先注册");
            return result;
        }

        if (!userByUserName.getUserPwd().equals(DigestUtils.md5DigestAsHex(user.getUserPwd().getBytes()))) {
            result.setCode(400);  //登录失败
            result.setMsg("密码错误");
            return result;
        }
        //生成token
        String token = JwtUtils.createJwt(userByUserName);
        //将用户信息放入redis中
        redisTemplate.opsForHash().put("user",userByUserName.getUserId()+"",token);
        redisTemplate.expire("user",60*60,TimeUnit.SECONDS);
        result.setCode(200);  //登录成功
        result.setMsg("登录成功");
        result.setData(token);
        return result;
    }

    //用户注册
    @Override
    public Result register(User user,String code) {
        Result result = new Result();
        String userName = user.getUserName();
        String userPwd = user.getUserPwd();
        String phone = user.getPhone();
        if (StringUtils.isEmpty(userName)) {
            result.setCode(400);  //注册失败
            result.setMsg("请输入账号");
            return result;
        }
        if (StringUtils.isEmpty(userPwd)) {
            result.setCode(400);  //注册失败
            result.setMsg("请输入密码");
            return result;
        }
        if (StringUtils.isEmpty(phone)) {
            result.setCode(400);  //注册失败
            result.setMsg("请输入手机号");
            return result;
        }
        if (StringUtils.isEmpty(code)) {
            result.setCode(400);  //注册失败
            result.setMsg("请输入验证码");
            return result;
        }
        //账号是否注册验证
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userName", userName);
        //数据库中查到的用户
        User userByUserName = userMapper.selectOneByExample(example);
        if (userByUserName != null){
            result.setCode(400);  //注册失败
            result.setMsg("该账号已存在！");
            return result;
        }
        //比较验证码是否相同
        String phoneCode = (String) redisTemplate.opsForHash().get("phoneCode", user.getPhone());
        if (phoneCode == null){
            result.setCode(400);  //注册失败
            result.setMsg("验证码已失效！");
            return result;
        }
        if (!phoneCode.equals(code)){
            result.setCode(400);  //注册失败
            result.setMsg("验证码错误！");
            return result;
        }
        //添加一个用户
        //对密码加密
        user.setUserPwd(DigestUtils.md5DigestAsHex(user.getUserPwd().getBytes()));
        user.setUserState(0); //设置身份证验证状态
        user.setUserMoney((double) 0);
        int i = userMapper.insert(user);
        if (i>0){
            result.setCode(200);  //注册成功
            result.setMsg("注册成功，请去登录！");
            return result;
        }
        //删除验证码信息
        redisTemplate.opsForHash().delete("phoneCode", user.getPhone());
        result.setCode(400);  //注册失败
        result.setMsg("注册失败，请重新注册！");
        return result;
    }

    //加载当前用户信息
    @Override
    public Result loadUser(String token) {
        Result result = new Result();
        Claims claims = JwtUtils.parseToken(token);
        Object userIdString = claims.get("userId");
        int userId = Integer.parseInt(String.valueOf(userIdString));
        User user = userMapper.selectByPrimaryKey(userId);
        user.setUserPwd("");
        result.setCode(200);
        result.setData(user);
        return result;
    }

    //根据用户id查询用户信息
    @Override
    public Result findUser(Integer userId) {
        Result result = new Result();
        User user = userMapper.selectByPrimaryKey(userId);
        result.setData(user);
        return result;
    }

    //根据用户id更新余额
    @Override
    public Result updateMoney(User user) {
        Result result = new Result();
        int i = userMapper.updateByPrimaryKeySelective(user);
        if (i>0){
            result.setCode(200);
            result.setMsg("更新余额成功！");
            return result;
        }
        result.setCode(400);
        result.setMsg("更新余额失败！");
        return result;
    }

    //注销
    @Override
    public Result logout(String token) {
        Result result = new Result();
        //获取当前用户id
        Claims claims = JwtUtils.parseToken(token);
        Object userIdString = claims.get("userId");
        int userId = Integer.parseInt(String.valueOf(userIdString));
        //清除redis中用户信息
        redisTemplate.opsForHash().delete("user",userId+"");
        result.setCode(200);
        return result;
    }

    //发送手机验证码
    @Override
    public Result getCode(String phone) {
        Result result = new Result();
        //发送验证码
        //随机生成6位数字
        String code = "";
        for (int i = 0; i <6 ; i++) {
            int codeItem =(int) (Math.random() * 10);
            code += codeItem+"";
        }
        //请求参数设置
       /* Map<String, String> params = new HashMap<String, String>();
        params.put("apiKey", "wpgSDczabbae735150076b80620435ec62fae12eb68f06d");
        params.put("phoneNum", phone);
        params.put("templateID", "10822");
        params.put("params", JSON.toJSONString(code));
        String phoneResult = PhoneCodeUtils.proxyToDesURL(params);*/
        redisTemplate.opsForHash().put("phoneCode",phone,code);
        redisTemplate.expire("phoneCode",5,TimeUnit.MINUTES);
        result.setCode(200);
        result.setMsg("验证码发送成功，有效时间五分钟");
        return result;
    }

    //身份验证
    @Override
    public Result identity(User user) {
        Result result = new Result();
        Identity identity = Tools.identity(user.getUserTname(), user.getUserCard());
        if (identity.getStatus() == 1) {
            user.setUserState(1);
            int i = this.userMapper.updateByPrimaryKeySelective(user);
            if (i > 0) {
                String token = JwtUtils.createJwt(user);
                redisTemplate.opsForHash().put("user",user.getUserId()+"",token);
                redisTemplate.expire("user",60*60,TimeUnit.SECONDS);
                result.setCode(200);
                result.setMsg(identity.getMsg());
                result.setData(token);
                return result;
            } else {
                return result;
            }
        } else {
            result.setCode(400);
            result.setMsg(identity.getMsg());
            return result;
        }
    }

    //验证用户是否实名认证
    @Override
    public Result checkCard(String token) {
        Result result = new Result();
        Claims claims = JwtUtils.parseToken(token);
        Object userIdString = claims.get("userId");
        int userId = Integer.parseInt(String.valueOf(userIdString));
        User user = userMapper.selectByPrimaryKey(userId);
        if (user.getUserState() == 0){
            result.setCode(401);
            result.setMsg("您还未实名认证");
            return result;
        }
        result.setCode(200);
        return result;
    }

    //充值提现
    @Override
    public Result alterMoney(double money, String token) {
        Result result = new Result();
        Claims claims = JwtUtils.parseToken(token);
        Object userIdString = claims.get("userId");
        int userId = Integer.parseInt(String.valueOf(userIdString));
        User userById = userMapper.selectByPrimaryKey(userId);
        userById.setUserMoney(userById.getUserMoney()+ money);
        int i = userMapper.updateByPrimaryKeySelective(userById);
        MoneyRecord moneyRecord = new MoneyRecord();
        moneyRecord.setRecordUid(userId);
        if (money>0){
            moneyRecord.setRecordType(0);
            moneyRecord.setRecordMoney(money);
        }else {
            moneyRecord.setRecordType(1);
            moneyRecord.setRecordMoney(0-money);
        }
        moneyRecord.setRecordTime(new Date());
        int insert = moneyRecordMapper.insert(moneyRecord);
        if (i>0 && insert > 0){
            result.setCode(200);
            result.setMsg("成功");
            return result;
        }
        result.setCode(200);
        result.setMsg("失败");
        return result;
    }

    //加载充值记录信息
    @Override
    public Result record(int page,int pageSize,int type,String token) {
        Result result = new Result();
        Claims claims = JwtUtils.parseToken(token);
        Object userIdString = claims.get("userId");
        int userId = Integer.parseInt(String.valueOf(userIdString));
        Example example = new Example(MoneyRecord.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("recordUid",userId);
        if (type != -1){
            criteria.andEqualTo("recordType",type);
        }
        PageHelper.startPage(page,pageSize);
        example.setOrderByClause("record_time desc");
        List <MoneyRecord> moneyRecords = moneyRecordMapper.selectByExample(example);
        Page<MoneyRecord> plist = (Page <MoneyRecord>) moneyRecords;
        PageBean<MoneyRecord> pb = new PageBean <>(
                plist.getPageNum(),
                plist.getTotal(),
                plist.getPageSize(),
                plist.getPages(),
                plist.getResult()
        );
        result.setCode(200);
        result.setData(pb);
        return result;
    }
}
